package com.gzyj.server.service;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.gzyj.data.common.VehicleIncrement;
import com.gzyj.jtt808.common.GPSPosition;
import com.gzyj.jtt808.v2011.additionalinfo.JTT808_AddtionalInfo;
import com.gzyj.jtt808.v2011.protocol.subiao.JTT808_0x0200_0x64;
import com.gzyj.jtt808.v2011.protocol.subiao.JTT808_0x0200_0x65;
import com.gzyj.jtt808.v2013.enums.BusinessDataType;
import com.gzyj.server.config.LogConfig;
import com.gzyj.server.factory.jtt808.NetWorkSerrvice;
import com.gzyj.server.utils.PointUtils;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class GPSService {


    @Autowired
    private ZdaqService zdaqService;

    @Value("${zdaq.fileserver.ip}")
    private String SafeAttachmentIpAddress;

    @Value("${zdaq.fileserver.port}")
    private int SafeAttachmentTcpPort;

    @Value("${zdaq.fileserver.udpport}")
    private int SafeAttachmentUdpPort;

    @Resource(name = "clusterRedisTemplate")
    private RedisTemplate<String, Object> clusterRedisTemplate;

    @Autowired
    private KafkaTemplate<String, Object> kafkaTemplate;

    @Value("${kafka.queue.gps}")
    private String kafka_topic_gps;

    @Value("${redis.key.yjzdaqAlarmVeh}")
    private String RedisKey_YjzdaqAlarmVeh;

    @Value("${kafka.queue.shfalarm}")
    private String shfalarm;

    @Autowired
    private NetWorkSerrvice netWorkSerrvice;

    @Autowired
    private YjGpsAddrService yjGpsAddrService;

    public void processZdaq(VehicleIncrement vehicleInfo, GPSPosition gps) {
        if (CollectionUtil.isNotEmpty(gps.getGnssDataAdditionalInfo())) {
            if (gps.getVersion().equalsIgnoreCase("2019")) {

            } else {

                for (JTT808_AddtionalInfo addtionalInfo : gps.getGnssDataAdditionalInfo()) {
                    if (addtionalInfo.getID() == 0x64) {
                        //ADAS
                        JTT808_0x0200_0x64 jtt808_0x0200_0x64 = (JTT808_0x0200_0x64) addtionalInfo;
                        String platformId = UUID.randomUUID().toString().replaceAll("-", "");
                        gps.setJtt808_0x64_platformId(platformId);

                        zdaqService.DisposeTTSSuBiao(vehicleInfo, jtt808_0x0200_0x64);

                        if (jtt808_0x0200_0x64.AlarmIdentification.AttachCount > 0) {
                            // 下发主动安全附件指令
                            com.gzyj.jtt808.v2013.protocol.subiao.JTT808_0x9208 main = new com.gzyj.jtt808.v2013.protocol.subiao.JTT808_0x9208() {{

                                AlarmId = platformId;
                                AlarmIdentification = jtt808_0x0200_0x64.AlarmIdentification;
                                AttachmentServerIP = SafeAttachmentIpAddress;
                                AttachmentServerIPTcpPort = SafeAttachmentTcpPort;
                                AttachmentServerIPUdpPort = SafeAttachmentUdpPort;
                                Retain = getEmptyBytes();
                            }};
                            clusterRedisTemplate.opsForValue().set(RedisKey_YjzdaqAlarmVeh + platformId, vehicleInfo, 8, TimeUnit.HOURS);
                            com.gzyj.jtt808.v2013.HeaderMsgBodyProperty headerMsgBodyProperty = new com.gzyj.jtt808.v2013.HeaderMsgBodyProperty();
                            headerMsgBodyProperty.setSubcontract(false);
                            headerMsgBodyProperty.setEncryptMethod(com.gzyj.jtt808.v2013.HeaderEncryptMethod.None);
                            main.getPackageHeader().setMsgBodyProperty(headerMsgBodyProperty);
                            main.getPackageHeader().setTerminalPhoneNo(vehicleInfo.getZongduanid());
                            ByteBuf data = main.encode();
                            ByteBuf tmpData = Unpooled.copiedBuffer(data);
                            netWorkSerrvice.send2Veh(vehicleInfo.getZongduanid(), data);

                            LogConfig.zdaqLog.info("主动安全下发 {} 指令 {} {}", BusinessDataType.find(main.getPackageHeader().getMsgId()), vehicleInfo.getZongduanid(), ByteBufUtil.hexDump(tmpData));


                        }


                    } else if (addtionalInfo.getID() == 0x65) {
                        //DSM
                        JTT808_0x0200_0x65 jtt808_0x0200_0x65 = (JTT808_0x0200_0x65) addtionalInfo;
                        String platformId = UUID.randomUUID().toString().replaceAll("-", "");
                        gps.setJtt808_0x65_platformId(platformId);

                        zdaqService.DisposeTTSSuBiao(vehicleInfo, jtt808_0x0200_0x65);


                        String alarmType = jtt808_0x0200_0x65.AlarmOrEventTypeString;
                        switch (jtt808_0x0200_0x65.AlarmOrEventTypeString) {
                            case "疲劳驾驶报警":
                            case "疲劳驾驶报警（生理疲劳）":
                                alarmType = "疲劳驾驶报警";
                                break;
                            case "接打手持电话报警":
                                alarmType = "接打电话报警";
                                break;
                            case "抽烟报警":
                                alarmType = "抽烟报警";
                                break;
                            case "长时间不目视前方报警":
                            case "不目视前方报警":
                                alarmType = "分神驾驶报警";
                                break;
                            case "未检测到驾驶员报警":
                            case "驾驶员异常报警":
                                alarmType = "未检测到驾驶员报警";
                                break;
                            case "探头遮挡报警":
                            case "驾驶员行为监测功能失效报警":
                            case "红外阻断墨镜失效报警":
                                alarmType = "探头遮挡报警";
                                break;
                            case "超时驾驶报警":
                                alarmType = "超时驾驶报警";
                                break;
                            case "未系安全带报警":
                                alarmType = "未系安全带报警";
                                break;
                            case "双手同时脱离方向盘报警":
                            case "双脱把报警":
                                alarmType = "双手同时脱离方向盘报警";
                                break;
                            case "玩手机报警":
                                alarmType = "玩手机报警";
                                break;
                            case "驾驶员变更事件":
                                alarmType = "驾驶员变更报警";
                                break;
                        }


                        // 推送到前端页面
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        JSONObject alarmJson = new JSONObject();
                        alarmJson.put("VehNo", vehicleInfo.getCheliangpaizhao());
                        alarmJson.put("VehId", vehicleInfo.getId());
                        alarmJson.put("PlateColor", vehicleInfo.getChepaiyanse());
                        alarmJson.put("AlarmFlag", 1);
                        alarmJson.put("Time", sdf.format(jtt808_0x0200_0x65.AlarmTime));
                        alarmJson.put("Note", alarmType);
                        alarmJson.put("Longitude", PointUtils.gps2double(jtt808_0x0200_0x65.Longitude));
                        alarmJson.put("Latitude", PointUtils.gps2double(jtt808_0x0200_0x65.Latitude));
                        alarmJson.put("Velocity", Byte.toUnsignedInt(jtt808_0x0200_0x65.Speed));
                        alarmJson.put("Angle", 0);
                        alarmJson.put("Local", 1);
                        alarmJson.put("Limited", 0);
                        alarmJson.put("RoadLimited", 0);
                        alarmJson.put("RoadName", yjGpsAddrService.getAddress(PointUtils.gps2double(jtt808_0x0200_0x65.Latitude), PointUtils.gps2double(jtt808_0x0200_0x65.Longitude)));
                        alarmJson.put("AlarmGuid", UUID.randomUUID().toString());
                        alarmJson.put("alarmSource", 4);
                        alarmJson.put("AlarmLevel", jtt808_0x0200_0x65.AlarmLevel);

                        kafkaTemplate.send(shfalarm, "shf-alarm", alarmJson.toJSONString());

                        if (jtt808_0x0200_0x65.AlarmIdentification.AttachCount > 0) {
                            // 下发上传主动安全附件
                            com.gzyj.jtt808.v2013.protocol.subiao.JTT808_0x9208 main = new com.gzyj.jtt808.v2013.protocol.subiao.JTT808_0x9208() {{

                                AlarmId = platformId; //UUID.randomUUID().toString().replaceAll("-", "");
                                AlarmIdentification = jtt808_0x0200_0x65.AlarmIdentification;
                                AttachmentServerIP = SafeAttachmentIpAddress;
                                AttachmentServerIPTcpPort = SafeAttachmentTcpPort;
                                AttachmentServerIPUdpPort = SafeAttachmentUdpPort;
                                Retain = getEmptyBytes();
                            }};

                            com.gzyj.jtt808.v2013.HeaderMsgBodyProperty headerMsgBodyProperty = new com.gzyj.jtt808.v2013.HeaderMsgBodyProperty();
                            headerMsgBodyProperty.setSubcontract(false);
                            headerMsgBodyProperty.setEncryptMethod(com.gzyj.jtt808.v2013.HeaderEncryptMethod.None);
                            main.getPackageHeader().setMsgBodyProperty(headerMsgBodyProperty);
                            main.getPackageHeader().setTerminalPhoneNo(vehicleInfo.getZongduanid());
                            ByteBuf data = main.encode();
                            ByteBuf outData = Unpooled.copiedBuffer(data);
                            netWorkSerrvice.send2Veh(vehicleInfo.getZongduanid(), data);

                            LogConfig.zdaqLog.info("主动安全下发 {} 指令 {} {}", BusinessDataType.find(main.getPackageHeader().getMsgId()), vehicleInfo.getZongduanid(), ByteBufUtil.hexDump(outData));

                        }


                    } else if (addtionalInfo.getID() == 0x67) {


                    } else if (addtionalInfo.getID() == 0x70) {

                    }
                }


            }
        }

        kafkaTemplate.send(kafka_topic_gps, "kafka_topic_gps", JSON.toJSONString(gps, SerializerFeature.DisableCircularReferenceDetect));

    }

    private byte[] getEmptyBytes() {
        byte[] data = new byte[16];
        for (int i = 0; i < 16; i++) {
            data[i] = (byte) 0;
        }
        return data;
    }


}
